package cn.tworice.blog.service.impl;

import cn.tworice.blog.dao.BlogDao;
import cn.tworice.blog.entity.BlogEntry;
import cn.tworice.blog.entity.CountIp;
import cn.tworice.blog.entity.ErrorInfo;
import cn.tworice.blog.service.BlogService;
import cn.tworice.blog.utils.CoreService;
import cn.tworice.blog.utils.RedisUtil;
import com.lmk.core.web.support.api.RequestResult;
import com.lmk.core.web.support.api.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Service
public class BlogServiceImpl implements BlogService {

    // redis工具类
    @Autowired
    private RedisUtil redisUtil;

    // 持久层
    @Autowired
    BlogDao blogDao;

    // 超时时间
    @Value("${blog.adminVerifyTime}")
    Long adminVerifyTime;

    // 登录可尝试的次数
    @Value("${blog.adminTryNumber}")
    Integer adminTryNumber;



    /**
     * 修改或添加博客条目信息
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult editEntry(BlogEntry blogEntry) {
        int i=0;
        if(blogEntry.getId()==null){
            blogEntry.setId(new Random().nextInt(99999999));
            // 添加
            i=blogDao.insertBlogEntry(blogEntry);
        }else {
            i=blogDao.updateBlogEntry(blogEntry);
            // 修改
        }
        if(i==1) {
            return new RequestResult(new StatusCode(204, "添加或修改博客条目成功！"));
        }else {
            return new RequestResult(new StatusCode(501, "添加或修改博客条目出现异常，请检查参数！"));
        }
    }

    /**
     * 遍历博客条目列表
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult queryBlogEntryList() {
        List<BlogEntry> list= blogDao.queryEntryList();
        RequestResult result = new RequestResult();
        result.setCode(new StatusCode(200,"请求成功"));
        result.appendData("entryList",list);
        return result;
    }

    /**
     * 验证登录
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult checkLogin(String password, String ipAddress) {
        RequestResult result=new RequestResult();
        try{
            // 获取当前已经尝试的次数
            Object val = redisUtil.getValByKey("adminLogin" + ipAddress);
            int i=0;

            if(val==null){
                // 第一次验证登录
                redisUtil.saveMailVerify("adminLogin"+ipAddress,0+"",adminVerifyTime);
            }else{
                i=Integer.parseInt(val+"");
                // 不是第一次验证登录
                if(i==adminTryNumber){
                    // 判断是否已经达到验证的上限次数
                    return new RequestResult(new StatusCode(403, "您的登录请求过于频繁，请于24小时后重试"));
                }
            }
            String token = "";
            // 判断密码是否正确
            int num=blogDao.isLogin(password);
            if(num==1){
                // 生成token
                token = CoreService.getLoginTicket(ipAddress);
                // 如果正确，设置缓存值为-1，表示已登录
                redisUtil.saveMailVerify("adminLogin"+ipAddress,-1+"",adminVerifyTime);
            }else {
                // 如果不正确，返回密码错误 请求的次数+1
                redisUtil.saveMailVerify("adminLogin"+ipAddress,(++i)+"",adminVerifyTime);

                return new RequestResult(new StatusCode(401, "密码错误，您还有"+(adminTryNumber-i)+"次机会"));
            }


            result.setCode(new StatusCode(200,"密码正确"));
            result.appendData("token",token);
            // 密码正确返回的数据

        }catch (Exception ex){
            ex.printStackTrace();
            log.error(ex.toString());
            return new RequestResult(new StatusCode(500, "服务器繁忙"));
        }
        return result;
    }

    /**
     * 判断当前IP是否需要登录
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult isLogin(String ipAddress) {
        Object val = redisUtil.getValByKey("adminLogin" + ipAddress);
        if(val==null){
            return new RequestResult(new StatusCode(401, "需要登录"));
        }else {
            int l = Integer.parseInt(val + "");

            if(l>-1){
                return new RequestResult(new StatusCode(401, "需要登录"));
            }else {
                return new RequestResult(new StatusCode(200, "已登录"));
            }
        }
    }

    /**
     * 根据ID删除博客条目
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult delEntryById(Integer id) {
        int i=blogDao.delEntryById(id);
        if(i==1){
            return new RequestResult(new StatusCode(200, "删除成功"));
        }else {
            return new RequestResult(new StatusCode(500, "删除失败"));
        }
    }

    /**
     * 根据ID列表批量删除博客信息
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public RequestResult delEntryByIds(List<Integer> ids) {

        try {
            int i = blogDao.delEntryByIds(ids);
            return new RequestResult(new StatusCode(200, "删除条目"+i+"条"));
        }catch (Exception ex){
            return new RequestResult(new StatusCode(500, "操作中止"));
        }

    }

    @Override
    public List<ErrorInfo> getErrorInfo(Long startTime, Long endTime) {
        if(endTime==0){
            endTime=System.currentTimeMillis();
        }

        return blogDao.queryErrorInfo(startTime, endTime);

    }

    @Override
    public List<CountIp> getUserInfo() {
        return blogDao.queryUserInfo();
    }

    /**
     * 返回此前n天的日期
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public List<String> getHistoryDate(int i) {
        List<String> list = new ArrayList<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");

        while (i!=0){
            // 获取当前时间
            Date time = calendar.getTime();
            String format = sdf.format(time);
            list.add(format);
            calendar.set(Calendar.DATE,calendar.get(Calendar.DATE)-1);
            i--;
        }

        return list;
    }

    /**
     * 获取前n天 每天访问的IP数，重复不计
     * n天内，IP访问的次数
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public Map<String,Object> getIpSumByDate(int i) {
        List<List<Map>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());

            String year = calendar.getWeekYear()+ "-";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            List<String> historyDate = getHistoryDate(i);
            for (String s : historyDate) {
                String date = year + s;
                Date parse = sdf.parse(date);
                long startTime = parse.getTime();
                long endTime=startTime+86400000L;
                // 当日IP和请求次数
                List<Map> sum=blogDao.queryIpSumByTime(startTime,endTime);
                res.add(sum);
                list.add(sum.size());
            }
        }catch (Exception ex){
            log.error("getIpSumByDate出现异常");
        }
        Map<String,Object> map = new HashMap();
        map.put("ipSum", list);
        map.put("sumByIp", res);
        return map;

    }

    /**
     * 获取前七天的异常数 近七日异常最多的接口  近七日异常最多的IP
     * @author 二饭
     * @email 1786705138@qq.com
     */
    @Override
    public Map<String,Object> getErrorSum(int i) {
        Map<String, Object> map = new HashMap<>();
        try{
            // 初始化日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            String year = calendar.getWeekYear()+ "-";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            long startTime = 0;

            List<Integer> list = new ArrayList<>(); // 初始化近七日的异常数列表
            List<String> historyDate = getHistoryDate(i); // 前七天的日期

            for (String s : historyDate) {
                String date = year + s;
                Date parse = sdf.parse(date);
                startTime = parse.getTime();
                long endTime=startTime+86400000L;
                list.add(blogDao.queryErrorSumByTime(startTime, endTime));
            }
            map.put("errorSumList", list);

            // 近七日异常最多的接口
            map.put("apiSumData",getApiSumError(startTime));

            // 近七日异常最多的IP
            map.put("ipSumData",getIpSumError(startTime));

        }catch (Exception ex){
            log.error("getIpSumByDate出现异常");
        }
        return map;
    }

    /**
     * 近七日异常最多的接口
     * @author 二饭
     * @email 1786705138@qq.com
     */
    private List<Map<String,Integer>> getApiSumError(Long startTime){
        return blogDao.queryApiSumError(startTime,System.currentTimeMillis());
    }

    private List<Map<String,Integer>> getIpSumError(Long startTime){
        return blogDao.queryIpSumError(startTime,System.currentTimeMillis());
    }


}
